package com.zxmzy.scaffold.core.ext

import android.graphics.Outline
import android.os.SystemClock
import android.view.View
import android.view.ViewGroup
import android.view.ViewOutlineProvider
import com.zxmzy.scaffold.core.R

/**
 * @author zhangxiaoming
 * @date 2023/7/27
 * @description View扩展
 */

/***
 * 点击事件的View扩展
 * @param block: (T) -> Unit 函数
 * @return Unit
 */
fun <T : View> T.click(block: (T) -> Unit) = setOnClickListener {
    block(it.saveAsUnChecked())
}

fun View.longClick(action: (view: View) -> Boolean) {
    setOnLongClickListener {
        action(it)
    }
}

fun View.onClick(wait: Long = 200, block: (View) -> Unit) {
    setOnClickListener(throttleClick(wait, block))
}

fun View.onDebounceClick(wait: Long = 200, block: (View) -> Unit) {
    setOnClickListener(debounceClick(wait, block))
}

fun throttleClick(wait: Long = 200, block: (View) -> Unit): View.OnClickListener {
    return View.OnClickListener { v ->
        val current = SystemClock.uptimeMillis()
        val lastClickTime = (v.getTag(R.id.click_time_stamp) as? Long) ?: 0
        if (current - lastClickTime > wait) {
            v.setTag(R.id.click_time_stamp, current)
            block(v)
        }
    }
}

fun debounceClick(wait: Long = 200, block: (View) -> Unit): View.OnClickListener {
    return View.OnClickListener { v ->
        var action = (v.getTag(R.id.click_debounce_action) as? DebounceAction)
        if (action == null) {
            action = DebounceAction(v, block)
        } else {
            action.block = block
        }
        v.removeCallbacks(action)
        v.postDelayed(action, wait)
    }
}

class DebounceAction(val view: View, var block: (View) -> Unit) : Runnable {
    override fun run() {
        if (view.isAttachedToWindow) {
            block(view)
        }
    }
}

/**
 * 设置View的margin
 * @param leftMargin 默认保留原来的
 * @param topMargin 默认是保留原来的
 * @param rightMargin 默认是保留原来的
 * @param bottomMargin 默认是保留原来的
 */
fun View.margin(
    leftMargin: Int = Int.MAX_VALUE,
    topMargin: Int = Int.MAX_VALUE,
    rightMargin: Int = Int.MAX_VALUE,
    bottomMargin: Int = Int.MAX_VALUE
): View {
    val params = layoutParams as ViewGroup.MarginLayoutParams
    if (leftMargin != Int.MAX_VALUE) {
        params.leftMargin = leftMargin
    }
    if (topMargin != Int.MAX_VALUE) {
        params.topMargin = topMargin
    }
    if (rightMargin != Int.MAX_VALUE) {
        params.rightMargin = rightMargin
    }
    if (bottomMargin != Int.MAX_VALUE) {
        params.bottomMargin = bottomMargin
    }
    layoutParams = params
    return this
}

fun View.show() {
    visibility = View.VISIBLE
}

fun View.hide() {
    visibility = View.INVISIBLE
}

fun View.goneHide() {
    visibility = View.GONE
}

/**
 * 设置View圆角
 */
fun View.clipViewCornerRadius(radius: Int) {
    if (radius > 0) {
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View?, outline: Outline?) {
                outline?.setRoundRect(
                    0,
                    0,
                    view?.width ?: 0,
                    view?.height ?: 0,
                    radius.toFloat()
                )
            }
        }
        clipToOutline = true
    } else {
        clipToOutline = false
    }
}

fun View.clipViewCornerTopRadius(radius: Int) {
    if (radius > 0) {
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View?, outline: Outline?) {
                outline?.setRoundRect(
                    0,
                    0,
                    view?.width ?: 0,
                    view?.height?.plus(radius) ?: 0,
                    radius.toFloat()
                )
            }
        }
        clipToOutline = true
    } else {
        clipToOutline = false
    }
}

/**
 * 设置View底部圆角
 */
fun View.clipViewCornerBottomRadius(radius: Int) {
    if (radius > 0) {
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View?, outline: Outline?) {
                outline?.setRoundRect(
                    0,
                    -radius,
                    view?.width ?: 0,
                    view?.height ?: 0,
                    radius.toFloat()
                )
            }
        }
        clipToOutline = true
    } else {
        clipToOutline = false
    }
}